package com.ruicar.afs.cloud.apply.pre.loan.mq.sender.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.aggregate.dto.VinCheckDto;
import com.ruicar.afs.cloud.apply.business.mq.config.ArchiveConfig;
import com.ruicar.afs.cloud.apply.business.service.ApplyRecordDetailsService;
import com.ruicar.afs.cloud.apply.business.service.ArchiveMQService;
import com.ruicar.afs.cloud.apply.common.entity.*;
import com.ruicar.afs.cloud.apply.common.utils.ApplyConstants;
import com.ruicar.afs.cloud.apply.contract.condition.GpsCondition;
import com.ruicar.afs.cloud.apply.contract.service.*;
import com.ruicar.afs.cloud.apply.contract.vo.ContractEntryCollectVO;
import com.ruicar.afs.cloud.apply.contract.vo.GpsInstallVO;
import com.ruicar.afs.cloud.apply.pre.loan.condition.CaseSubmitInfoCondition;
import com.ruicar.afs.cloud.apply.pre.loan.condition.ContractCancelCondition;
import com.ruicar.afs.cloud.apply.pre.loan.mq.sender.CaseLoanInfoSender;
import com.ruicar.afs.cloud.apply.pre.loan.mq.sender.impl.CaseLoanInfoSenderImpl;
import com.ruicar.afs.cloud.apply.pre.loan.service.ApplyCarDetailsService;
import com.ruicar.afs.cloud.apply.pre.loan.service.ApplyOrderInfoService;
import com.ruicar.afs.cloud.bizcommon.gps.service.GpsOLEService;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.ApplyStatusEnum;
import com.ruicar.afs.cloud.common.modules.dto.mq.loan.LoanApplySubmitInfo;
import com.ruicar.afs.cloud.common.modules.dto.mq.loan.LoanDiscardDTO;
import com.ruicar.afs.cloud.common.modules.dto.mq.loan.gpsdto.ApplyGpsInfoDto;
import com.ruicar.afs.cloud.common.mq.rabbit.message.AfsTransEntity;
import com.ruicar.afs.cloud.image.entity.ComAttachmentManagement;
import com.ruicar.afs.cloud.image.service.ComAttaManageService;
import com.ruicar.afs.cloud.image.service.ComAttachmentFileService;
import com.ruicar.afs.cloud.image.service.ComAttachmentManagementService;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author panhj
 */
@RestController
@AllArgsConstructor
@RequestMapping("/loan")
@ConditionalOnProperty(prefix = "com.ruicar.afs.cloud.mq.rabbit", name = "enable")
@Slf4j
public class CaseLoanController {
    private final CaseLoanInfoSender sender;
    private final CaseLoanInfoSenderImpl service;
    private final ApplyRecordDetailsService applyRecordDetailsService;
    private final ApplyReturnRecordService applyReturnRecordService;
    private final ComAttachmentFileService comAttachmentFileService;
    private final ComAttaManageService comAttaManageService;
    private final ApplyCarDetailsService applyCarDetailsService;
    private final ApplyGpsInfoService applyGpsInfoService;
    private final ApplyGpsOrderHistoryService applyGpsOrderHistoryService;
    private final ApplyContractInfoService applyContractInfoService;
    private final ArchiveMQService archiveMQService;
    private final GpsOLEService gpsOLEService;
    private final ApplyOrderInfoService applyOrderInfoService;
    private final ApplyBankCardService applyBankCardService;
    private final ComAttachmentManagementService comAttachmentManagementService;
    /**
     * 提交案件-发送消息到消费者
     *
     * @return
     */
    @PostMapping("/loanApplySubmitInfo")
    @ApiOperation("提交案件")
    public IResponse loanApplySubmitInfo(@RequestBody CaseSubmitInfoCondition condition) {
        ApplyCarDetails applyCarDetails = applyCarDetailsService.getCarDetailsByApplyNo(condition.getApplyNo());
        ApplyOrderInfo applyOrderInfo = applyOrderInfoService.getOrderInfoByApplyNo(condition.getApplyNo());
        if (ObjectUtil.isNull(applyCarDetails)) {
            return new IResponse().fail("车辆信息获取失败");
        } else {
            List<VinCheckDto> list = applyOrderInfoService.getLoanVinCheck(applyCarDetails.getCarVin());
            if (list != null && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    if (!list.get(i).getApplicationNo().equals(condition.getApplyNo())) {
                        return new IResponse().fail("该VIN号已被使用，请重新填写");
                    }
                }
            }
        }
        String contractNo = condition.getContractNo();
        log.info("提交案件合同号:{}", contractNo);
        WorkflowRecordDetails detailsServiceOne = this.applyRecordDetailsService.getOne(Wrappers.<WorkflowRecordDetails>query().lambda()
                .eq(WorkflowRecordDetails::getBusinessNo, contractNo)
                .eq(StringUtil.isNotEmpty(contractNo), WorkflowRecordDetails::getApproveResult, ApplyStatusEnum.LOAN_RETURN.getState())
                .orderByDesc(WorkflowRecordDetails::getCreateTime)
                .last("LIMIT 1"));
        ApplyGpsInfo applyGpsInfo = applyGpsInfoService.getOne(Wrappers.<ApplyGpsInfo>query().lambda().eq(ApplyGpsInfo::getApplyNo, condition.getApplyNo()));
        ApplyGpsOrderHistory applyGpsOrderHistory = new ApplyGpsOrderHistory();
        BeanUtils.copyProperties(applyGpsInfo, applyGpsOrderHistory);
        applyGpsOrderHistory.setInstallTime(applyGpsInfo.getPreInstallTime());
        applyGpsOrderHistoryService.saveOrUpdate(applyGpsOrderHistory);
        ApplyContractInfo applyOrderInfo1 = applyContractInfoService.getOne(Wrappers.<ApplyContractInfo>query().lambda()
                .eq(ApplyContractInfo::getApplyNo, condition.getApplyNo()));
        ApplyBankCard applyBankCard = applyBankCardService.getBankCardByApplyNo(condition.getApplyNo());
        if (applyOrderInfo1.getLendingFirstDate() == null) {
            applyOrderInfo1.setLendingFirstDate(new Date());
        }
        applyOrderInfo1.setDeptId(SecurityUtils.getUser().getDeptId().toString());
        applyOrderInfo1.setLoanReporter(SecurityUtils.getUser().getUsername());
        if (condition.getSubmitFlag().equals(ApplyConstants.CONTRACT_STATUS_BACK)) {
            applyOrderInfo1.setContractStatus(ApplyConstants.CONTRACT_STATUS_APPROVE);
            if (ObjectUtil.isNotNull(detailsServiceOne)) {
                List<ApplyReturnRecord> list = applyReturnRecordService.list(Wrappers.<ApplyReturnRecord>query().lambda().eq(ApplyReturnRecord::getRecordId,detailsServiceOne.getId()));
                if(list.size()>0){
                    for(ApplyReturnRecord applyReturnRecord:list){
                        ComAttachmentManagement comAttachmentManagement=comAttachmentManagementService.getAttachmentManagement("loanApply","repayBankCardMerge");
                        ComAttachmentManagement comAttachmentManagement1=comAttachmentManagementService.getAttachmentManagement("loanApply","repayIdCardMerge");
                        if(comAttachmentManagement!=null && applyReturnRecord.getReturnType().equals(comAttachmentManagement.getId().toString())){
                            comAttaManageService.mergeRepayBankCard(applyBankCard.getContractNo(), applyBankCard.getAccountName(), applyBankCard.getAccountNo());
                        }
                        if(comAttachmentManagement1!=null && applyReturnRecord.getReturnType().equals(comAttachmentManagement1.getId().toString())){
                            comAttaManageService.mergeRepayIdCard(applyBankCard.getContractNo(), applyBankCard.getAccountName(), applyBankCard.getCertNo());
                        }
                    }
                }
            }
        } else {
            comAttaManageService.mergeRepayIdCard(applyBankCard.getContractNo(), applyBankCard.getAccountName(), applyBankCard.getCertNo());
            comAttaManageService.mergeRepayBankCard(applyBankCard.getContractNo(), applyBankCard.getAccountName(), applyBankCard.getAccountNo());
            applyOrderInfo1.setContractStatus(ApplyConstants.CONTRACT_STATUS_SUBMIT);
        }
        if (ObjectUtil.isNotNull(detailsServiceOne)) {
            if (ApplyStatusEnum.LOAN_RETURN.getState().equals(detailsServiceOne.getApproveResult())) {
                List<ApplyReturnRecord> applyReturnRecordList = this.applyReturnRecordService.list(Wrappers.<ApplyReturnRecord>query().lambda()
                        .eq(StringUtil.isNotEmpty(contractNo), ApplyReturnRecord::getContractNo, contractNo)
                        .eq(ApplyReturnRecord::getRecordId, detailsServiceOne.getId()));
                if (CollectionUtil.isNotEmpty(applyReturnRecordList)) {
                    List<String> returnTypeList = new ArrayList<>();
                    applyReturnRecordList.stream().forEach(applyReturnRecord -> {
                        returnTypeList.add(applyReturnRecord.getReturnType());
                    });
                    log.info("退回提交案件:{},返回类型{}:", contractNo, returnTypeList);
                    //放款申请再次提交时，修改文件版本号，并修改新上传的文件为不合格，放款审核时修改文件状态为合格
                    comAttaManageService.updateFileVersionByBusiNoForLoan(contractNo, returnTypeList);
                }
            }
        } else {
            //如果是首次提交,修改文件状态
            this.comAttachmentFileService.updateFileStatusByBusiNo(contractNo);
        }
        AfsTransEntity<LoanApplySubmitInfo> loanApplySubmitInfoAfsTransEntity = this.service.returnLoanApplySubmitInfo(condition);
        sender.sendForCaseLoanSubmit(loanApplySubmitInfoAfsTransEntity);
        applyContractInfoService.updateById(applyOrderInfo1);
        return IResponse.success("消息发送成功");
    }

    /**
     * 提交GPS二次派单信息至案件
     *
     * @return
     */
    @PostMapping("/gpsInfoSubmitInfo")
    @ApiOperation("提交案件")
    public IResponse gpsInfoSubmitInfo(@RequestBody ContractEntryCollectVO vo) {
        GpsCondition gpsCondition = new GpsCondition();
        BeanUtils.copyProperties(vo.getGpsInfo(), gpsCondition);
        JSONObject result = applyGpsInfoService.getAllOrderInfoByAppCode(gpsCondition.getCarId());
        Boolean success = result.getBoolean("Success");
        if (success) {
            String orderStatus = result.getJSONObject("Data").getJSONObject("orderbaseinfo").getString("OrderStatus");
            String waitDistribute = "等待派单";
            String waitInstall = "等待加装";
            if (orderStatus.equals(waitDistribute) || orderStatus.equals(waitInstall)) {
                GpsInstallVO installVO = applyGpsInfoService.getGpsPreInstallInfo(gpsCondition);
                // 调用GPS派单
                JSONObject result1 = applyGpsInfoService.updateOrderWithVpsInfos(gpsCondition, installVO);
                Boolean success1 = result1.getBoolean("Success");
                if (success1) {
                    vo.getGpsInfo().setOrderNo(result1.getJSONObject("Data").getString("Id"));
                    boolean result2 = applyGpsInfoService.updateById(vo.getGpsInfo());
                    ApplyGpsOrderHistory history = new ApplyGpsOrderHistory();
                    BeanUtils.copyProperties(vo.getGpsInfo(), history);
                    //置空id
                    history.setId(null);
                    history.setInstallTime(gpsCondition.getPreInstallTime());
                    boolean result3 = applyGpsOrderHistoryService.save(history);
                    if (result2 && result3) {
                        ApplyContractInfo applyContractInfo = applyContractInfoService.getOne(Wrappers.<ApplyContractInfo>query().lambda().eq(ApplyContractInfo::getApplyNo, gpsCondition.getApplyNo()));
                        applyContractInfo.setGpsStatus(ApplyConstants.SEND_TASK);
                        applyContractInfoService.updateById(applyContractInfo);
                        AfsTransEntity<ApplyGpsInfoDto> applyGpsInfoDtoAfsTransEntity = this.service.returngpsInfoSubmitInfo(vo);
                        sender.sendForCaseGpsInfoSubmit(applyGpsInfoDtoAfsTransEntity);
                        return new IResponse().setMsg("改派成功");
                    } else {
                        return new IResponse().setCode("9999").setMsg("派单成功,但数据保存出现错误，请联系业务人员处理");
                    }

                } else {
                    return new IResponse().setCode("9999").setMsg(result.getString("AllMessages"));
                }
            } else {
                return new IResponse().setCode("9999").setMsg("当前状态不可二次派单！！！");
            }
        } else {
            return new IResponse().setCode("9999").setMsg("获取工单信息失败");
        }
    }

    @ApiOperation("放款申请-取消")
    @PostMapping("/saveCancel")
    public IResponse saveCancel(@RequestBody ContractCancelCondition condition) {
        ApplyContractInfo applyContractInfo = applyContractInfoService.getOne(Wrappers.<ApplyContractInfo>query().lambda().eq(ApplyContractInfo::getContractNo, condition.getContractNo()));
        if (applyContractInfo != null) {
            //归档mq推送放款主动取消
            if (!condition.getCancelOrWithdraw().equals(ApplyConstants.LOAN_BACK)) {
                ApplyGpsInfo applyGpsInfo = applyGpsInfoService.getOne(Wrappers.<ApplyGpsInfo>query().lambda().eq(ApplyGpsInfo::getContractNo, applyContractInfo.getContractNo()));
                if (applyGpsInfo != null) {
                    if (applyGpsInfo.getGpsProductNo() != null) {
                        ApplyCarDetails applyCarDetails = applyCarDetailsService.getCarDetailsByApplyNo(applyContractInfo.getApplyNo());
                        if (applyCarDetails != null) {
                            JSONObject result = gpsOLEService.cancelOrderWithVpsInfos(applyCarDetails.getId().toString());
                            Boolean success = result.getBoolean("Success");
                            if (!success) {
                                return new IResponse().fail("GPS撤销失败");
                            } else {
                                applyContractInfo.setGpsStatus(ApplyConstants.CANCEL_INSTALL);
                                applyContractInfoService.updateById(applyContractInfo);
                            }
                        } else {
                            return new IResponse().fail("获取车辆信息失败");
                        }
                    }
                }
            }
            if (condition.getCancelOrWithdraw().equals(ApplyConstants.LOAN_BACK)) {
                applyContractInfo.setContractStatus(ApplyConstants.CONTRACT_STATUS_01);
            } else {
                applyContractInfo.setContractStatus(ApplyConstants.CONTRACT_STATUS_CANCEL);
            }
            applyContractInfo.setUpdateTime(new Date());
            applyContractInfo.setCancelDate(new Date());
            applyContractInfo.setCreateBy(SecurityUtils.getUsername());
            applyContractInfoService.updateById(applyContractInfo);
            ApplyOrderInfo applyOrderInfo=applyOrderInfoService.getOrderInfoByApplyNo(applyContractInfo.getApplyNo());
            applyOrderInfo.setCancelDate(new Date());
            applyOrderInfo.setApplyStatus(ApplyConstants.APPLY_STATUS_CANCEL);
            applyOrderInfoService.updateById(applyOrderInfo);
            archiveMQService.archivePushMQ(applyContractInfo.getId().toString(), applyContractInfo.getContractNo(), applyContractInfo.getApplyNo(), ArchiveConfig.wwcontract_discard);
            condition.setApplyNo(applyContractInfo.getApplyNo());
            AfsTransEntity<LoanDiscardDTO> loanDiscardDTOAfsTransEntity = this.service.contractCancel(condition);
            sender.sendContractCancelToCase(loanDiscardDTOAfsTransEntity);
        }
        return IResponse.success("操作成功");
    }
}
